package org.lab.tracecash.web.rest.impl;

import javax.persistence.EntityManager;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;

import org.lab.tracecash.common.model.Message;
import org.lab.tracecash.common.model.SearchParams;
import org.lab.tracecash.common.model.SearchResults;
import org.lab.tracecash.model.Account;
import org.lab.tracecash.model.Transaction;
import org.lab.tracecash.web.rest.AbstractRestEntityService;

@Path("/transaction")
@Consumes({ "application/json; charset=UTF-8" })
@Produces({ "application/json; charset=UTF-8" })
public class TransactionRestService extends AbstractRestEntityService<Transaction> {

	@GET
	@Path("/id/{id}")
	public Transaction findById(@PathParam("id") Long id) {
		return super.findById(id);
	}

	@GET
	@Path("/find")
	public SearchResults<Transaction> find(@QueryParam("q") String queryString, @QueryParam("p") Long page, @QueryParam("n") Integer pageSize) {
		SearchParams searchParams = new SearchParams();
		searchParams.setQueryString(queryString);
		searchParams.setCurrentPage(page);
		searchParams.setPageSize(pageSize);
		return find(searchParams);
	}

	@GET
	@Path("/account/{id}")
	public SearchResults<Transaction> findByAccount(@PathParam("id") Long id, @QueryParam("p") Long page, @QueryParam("n") Integer pageSize) {
		String queryString = String.format("from.id==%s,to.id=%s", id, id);
		SearchParams searchParams = new SearchParams();
		searchParams.setCurrentPage(page);
		searchParams.setPageSize(pageSize);
		searchParams.setQueryString(queryString);
		return find(searchParams);
	}

	@POST
	@Path("/merge")
	public Message<Transaction> update(Transaction transaction) {
		EntityManager entityManager = entityManagerProvider.get();
		Transaction current = entityManager.find(Transaction.class, transaction.getId());
		if (!entityManager.getTransaction().isActive()) {
			entityManager.getTransaction().begin();
		}
		current.setFrom(entityManager.find(Account.class, transaction.getFrom().getId()));
		current.setTo(entityManager.find(Account.class, transaction.getTo().getId()));
		current.setChecked(transaction.getChecked());
		current.setDesc(transaction.getDesc());
		current.setLongDesc(transaction.getLongDesc());
		entityManager.merge(current);
		entityManager.getTransaction().commit();
		if (transaction.getAmount() != null) {
			current.setAmount(transaction.getAmount());
		}
		return new Message<Transaction>("0", "Transacción actualizada", current);
	}

	@Override
	protected void buildOrderCriteria(CriteriaQuery<Transaction> criteria, CriteriaBuilder builder, Root<Transaction> root) {
		criteria.orderBy(builder.asc(root.<Long> get("valueDate")));
	}

	@Override
	protected Class<Transaction> getEntityClass() {
		return Transaction.class;
	}
}
